6 Pressurepath
In this chapter, we will see what a pressurepath object is and how to use it to compute the altitude of the bird throughout its trajectory.
Let’s load the tag from the Great Reed Warbler (18LX) created in the [advanced tutorial].
load("./data/interim/18LX.Rdata")6.1 Timeseries at a single position
Before creating a full pressurepath, we start with the basic building block of a pressurepath, which is to retrieve the pressure timeseries from ERA5 at a single location with geopressure_timeseries.
geopressure_timeseries relies on the pressure timeseries entry point of GeoPressureAPI, which return the timeseries of pressure at a given latitude and longitude.
Let’s start by retrieving the pressure at the known site of equipment, querying the same date as the first stationary period.
ts <- geopressure_timeseries(
lat = tag$stap$known_lat[1],
lon = tag$stap$known_lon[1],
start_time = tag$stap$start[1],
end_time = tag$stap$end[1]
)##
⠙ Generate request (on GeoPressureAPI)
✔ Generate request (on GeoPressureAPI) [1.2s]
##
⠙ Sending request
✔ Sending request [3.1s]
##
⠙ Compute timeseries (on GEE server) and download csv
✔ Compute timeseries (on GEE server) and download csv […
We can compare the retrieved ERA5 pressure to the pressure measured on the Great Reed Warbler:
p <- ggplot() +
geom_line(data = ts, aes(x = date, y = pressure_era5, colour = "ERA5")) +
geom_line(data = tag$pressure[tag$pressure$stap_id == 1, ], aes(x = date, y = value, colour = "tag")) +
theme_bw() +
ylab("Pressure (hPa)") +
scale_color_manual(values = c("ERA5" = "black", "tag" = "red"))
layout(ggplotly(p), legend = list(orientation = "h"))Nostalgia
This was the figure that made me realize the potential of pressure measurement to determine birds’ position! The accuracy of the reanalysis data and the precision of the sensor were such that a timeseries of pressure had only a few possible options on the map!
6.2 Pressurepath
What is a pressurepath?
You can think of a pressurepath as the timeseries of pressure that a tag would record on a bird traveling along a specified path. To do that, pressurepath_create() calls geopressure_timeseries() for each stationary period and combines the resulting timeseries of ERA5 pressure.
The pressurepath data.frame returned also contains the original pressure pressure_tag which can be very helpful for labelling and the altitude of the bird corrected for the natural variation of pressure.
pressurepath <- pressurepath_create(tag,
path = path_most_likely,
include_flight = TRUE
)##
⠙ Generate requests (on GeoPressureAPI) for 29 stationa…
✔ Generate requests (on GeoPressureAPI) for 29 stationa…
##
⠙ 1/29 ETA: 5s |
⠹ 2/29 ETA: 6s |
⠸ 3/29 ETA: 6s |
⠼ 4/29 ETA: 6s |
⠴ 5/29 ETA: 6s |
⠦ 6/29 ETA: 7s |
⠧ 7/29 ETA: 7s |
⠇ 8/29 ETA: 7s |
⠏ 9/29 ETA: 6s |
⠋ 10/29 ETA: 6s |
⠙ 11/29 ETA: 6s |
⠹ 12/29 ETA: 6s |
⠸ 13/29 ETA: 6s |
⠼ 14/29 ETA: 6s |
⠴ 15/29 ETA: 5s |
⠦ 16/29 ETA: 5s |
⠧ 17/29 ETA: 5s |
⠇ 18/29 ETA: 5s |
⠏ 19/29 ETA: 4s |
⠋ 20/29 ETA: 4s |
⠙ 21/29 ETA: 4s |
⠹ 22/29 ETA: 3s |
⠸ 23/29 ETA: 3s |
⠼ 24/29 ETA: 3s |
⠴ 25/29 ETA: 2s |
⠦ 26/29 ETA: 2s |
⠧ 27/29 ETA: 1s |
⠇ 28/29 ETA: 1s |
⠙ Compute and download timeseries (on GEE server)
✔ Compute and download timeseries (on GEE server) [12ms]
##
⠙ 1/29 ETA: 1s |
⠹ 2/29 ETA: 1s |
⠸ 3/29 ETA: 1s |
⠼ 4/29 ETA: 1s |
⠴ 5/29 ETA: 16s |
⠦ 6/29 ETA: 13s |
⠧ 7/29 ETA: 11s |
⠇ 8/29 ETA: 10s |
⠏ 9/29 ETA: 12s |
⠋ 10/29 ETA: 11s |
⠙ 11/29 ETA: 11s |
⠹ 12/29 ETA: 11s |
⠸ 13/29 ETA: 10s |
⠼ 14/29 ETA: 10s |
⠴ 15/29 ETA: 13s |
⠦ 16/29 ETA: 11s |
⠧ 17/29 ETA: 10s |
⠇ 18/29 ETA: 14s |
⠏ 19/29 ETA: 12s |
⠋ 20/29 ETA: 13s |
⠙ 21/29 ETA: 11s |
⠹ 22/29 ETA: 9s |
⠸ 23/29 ETA: 7s |
⠼ 24/29 ETA: 6s |
⠴ 25/29 ETA: 5s |
⠦ 26/29 ETA: 3s |
⠧ 27/29 ETA: 2s |
⠇ 28/29 ETA: 1s |
Note that if a position on the path is over water, it is automatically moved to the closest point onshore as we use ERA5 Land.
plot_pressurepath(pressurepath)## Warning in abs(pp$error)/sd[pp$stap_id]: longer object length is not a multiple
## of shorter object length
6.3 Altitude
pressurepath is the best way to compute the altitude of the bird throughout its trajectory, including flights.
plot_pressurepath(pressurepath, type = "altitude")Why use GeoPressureAPI for altitude?
Computing the bird altitude \(z_{gl}\) from its pressure measurement \(P_{gl}\) is best performed with the barometric equation.
\[ z_{gl}=z_0 + \frac{T_0}{L_b} \left( \frac{P_{gl}}{P_0} \right) ^{\frac{RL_b}{g M}-1},\]
where \(L_b\) is the standard temperature lapse rate, \(R\) is the universal gas constant, \(g\) is the gravity constant and \(M\) is the molar mass of air.
It is typical to assume a standard atmosphere with fixed \(T_0=15°C\), \(P_0=1013.25 hPa\) and \(z_0=0 m\),
Lb <- -0.0065
R <- 8.31432
g0 <- 9.80665
M <- 0.0289644
T0 <- 273.15 + 15
P0 <- 1013.25
pressurepath$altitude_uncorrected <- T0 / Lb * ((pressurepath$pressure_tag / P0)^(-R * Lb / g0 / M) - 1)However, we know that pressure and temperature vary considerably over time and space, leading to approximation in the altitude estimated.
Using GeoPressureAPI, we can adjust the barometric equation with the actual ground-level pressure \(P_{ERA}\) and ground temperature \(T_{ERA}\) retrieved from ERA5 at the bird’s location \(x\), \[ z_{gl}(x)=z_{ERA5}(x) + \frac{T_{ERA5}(x)}{L_b} \left( \frac{P_{gl}}{P_{ERA5}(x)} \right) ^{\frac{RL_b}{g M}-1},\]
See more information on the GeoPressureAPI documentation
We can compare theses two altitudes for the first stationary period,
p <- ggplot(pressurepath[pressurepath$stap_id == 1, ]) +
geom_line(aes(x = date, y = altitude, colour = "Corrected elevation with ERA5")) +
geom_line(aes(x = date, y = altitude_uncorrected, colour = "Uncorrected elevation")) +
theme_bw() +
ylab("Pressure (hPa)") +
scale_color_manual(values = c("Corrected elevation with ERA5" = "black", "Uncorrected elevation" = "red"))
plotly::layout(plotly::ggplotly(p), legend = list(orientation = "h"))The uncorrected altitude estimate incorrectly produces a 200m amplitude error in the altitude due to the natural variation of pressure. In contrast, the corrected altitude shows that the Great Reed Warbler mostly stayed at the same location/altitude during the entire period.
How to estimate altitude during flight?
The correction for altitude requires knowing the actual position of the bird to retrieve the correct pressure and temperature at ground level. However, when the bird is flying, its position changes constantly, making the estimation of altitude more complicated.
The include_flight argument in pressurepath_create() is particularly useful here as it allows to compute altitude during the flight using the reference position of the previous/next stationary periods stap_ref.
To extract a single altitude estimate during a flight, I suggest using pressurepath2altitude() which conveniently combines the altitude estimates from the the previous and next stap_ref.
6.4 Save
The graph object can become extremely big for such models, and it might not be recommended to save it. Check its size with format(object.size(graph), units = "MB").
save(
tag,
# graph,
pressurepath,
path_most_likely,
path_simulation,
marginal,
file = "./data/interim/18LX.RData"
)